package com.yyoa.service.impl;

import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.google.common.collect.Lists;
import com.yyoa.Consts;
import com.yyoa.dao.UserDao;
import com.yyoa.entity.User;
import com.yyoa.model.Constraint;
import com.yyoa.model.Page;
import com.yyoa.model.SimpleConstraint;
import com.yyoa.service.UserService;
import com.yyoa.util.Constraints;
import com.yyoa.util.HexUtil;

@Service("userService")
@Transactional
public class UserServiceImpl implements UserService {

	// logger日志对象
	protected Logger log = Logger.getLogger(this.getClass());

	private UserDao userDao;

	@Autowired
	public void setUserDao(UserDao userDao) {
		this.userDao = userDao;
	}

	@Override
	public void addAdminUser(User user) {
		user.setPassword(getEncryptedPassword(user.getPassword()));
		user.setRole(User.ROLE_ADMIN);
		userDao.saveOrUpdate(user);
	}

	@Override
	public void addCommonUser(User user) {
		user.setPassword(getEncryptedPassword(Consts.INITPASSWORD));
		user.setRole(User.ROLE_COMMON);
		userDao.saveOrUpdate(user);
	}

	@Override
	public User getById(Long id) {
		return userDao.get(id);
	}

	@Override
	public User getByUserName(String userName) {
		return userDao.getByUserName(userName);
	}

	@Override
	public User getByEmail(String email) {
		return userDao.getByEmail(email);
	}

	@Override
	public User getByMobilePhone(String mobilePhone) {
		if (StringUtils.isEmpty(mobilePhone)) {
			return null;
		}
		return userDao.getByMobilePhone(Long.parseLong(mobilePhone));
	}

	@Override
	public User login(String userName, String password) {
		User dbUser = verifyUserName(userName);
		if (!validPassword(password, dbUser.getPassword())) {
			throw new RuntimeException("此用户名和密码不匹配。");
		}
		return dbUser;
	}

	@Override
	public boolean verifyUser(String userName, String mobilePhoneOrEmail) {
		User user = verifyUserName(userName);
		if (StringUtils.isNotEmpty(mobilePhoneOrEmail)) {
			if (mobilePhoneOrEmail.contains("@") && mobilePhoneOrEmail.equals(user.getEmail())) {
				log.info("Verify user email [" + mobilePhoneOrEmail + "] success.");
				return true;
			}

			try {
				if (Long.parseLong(mobilePhoneOrEmail) == user.getMobilePhone()) {
					log.info("Verify user mobile phone [" + mobilePhoneOrEmail + "] success.");
					return true;
				}
			} catch (Exception e) {
				log.info("Verify user fail.");
				return false;
			}
		}

		log.info("Verify user fail.");
		return false;
	}

	private User verifyUserName(String userName) {
		User dbUser = userDao.getByUserName(userName);
		if (dbUser == null) {
			throw new RuntimeException("此用户名 [" + userName + "] 不存在.");
		}
		return dbUser;
	}

	// private boolean verifyUser(String id, User dbUser) {
	// // modify
	// if (StringUtils.isNotEmpty(id)) {
	// if (dbUser != null && dbUser.getId() != Long.parseLong(id)) {
	// return true;
	// }
	// return false;
	// } else {
	// // add
	// return dbUser == null ? false : true;
	// }
	// }

	@Override
	public void resetPassword(String userName, String resetPassword) {
		User user = getByUserName(userName);
		user.setPassword(getEncryptedPassword(resetPassword));
		userDao.saveOrUpdate(user);
	}

	@Override
	public void updateUser(User user) {
		User dbUser;
		if (user.getId() != null) {
			dbUser = (User) userDao.get(user.getId());
		} else {
			dbUser = getByUserName(user.getUserName());
		}
		dbUser.setName(user.getName());
		dbUser.setEmail(user.getEmail());
		dbUser.setSex(user.getSex());
		dbUser.setDescribe(user.getDescribe());
		dbUser.setPhone(user.getPhone());
		dbUser.setMobilePhone(user.getMobilePhone());
		userDao.saveOrUpdate(dbUser);
	}

	@Override
	public Page<User> listUser(Page<User> page, Constraint constraint) {
		Constraint normalStatus = new SimpleConstraint("status", SimpleConstraint.COMPARE_EQUAL, User.STATUS_NORMAL);
		return userDao.findPage(page, Constraints.mergeConstraintByAnd(Lists.newArrayList(constraint, normalStatus)));
	}

	@Override
	public void deleteUser(String loginUserName, Long id) {
		User dbLoginUser = verifyUserName(loginUserName);
		if (dbLoginUser.getRole() != User.ROLE_ADMIN) {
			throw new RuntimeException("The user [useName:" + loginUserName + "] no power delete user.");
		}

		if (dbLoginUser.getId() == id) {
			throw new RuntimeException("Your can not delete yourself.");
		}

		User dbUser = userDao.get(id);
		if (dbUser == null) {
			throw new RuntimeException("Can not find user by id [" + id + "] in db.");
		}

		if (dbUser.getStatus().equals(User.STATUS_NORMAL)) {
			dbUser.setStatus(User.STATUS_DELETE);
			userDao.saveOrUpdate(dbUser);
		}
	}

	private String getEncryptedPassword(String unEncryptedPassword) {
		String encryptedPassword;
		try {
			encryptedPassword = HexUtil.getEncryptedPwd(unEncryptedPassword);
		} catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
			throw new RuntimeException("密码加密失败!", e);
		}

		return encryptedPassword;
	}

	private boolean validPassword(String unEncryptedPassword, String encryptedPassword) {
		boolean result = false;
		try {
			result = HexUtil.validPasswd(unEncryptedPassword, encryptedPassword);
		} catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
			throw new RuntimeException("密码错误!", e);
		}

		return result;
	}
}
